<?php

class Utilidades {
//<editor-fold defaultstate="collapsed" desc="Constantes">
  const ZONA_HORARIA = "America/Santiago";
  // enum Ambiente
  const AMBIENTE_EJECUCION_DEMO = "Demo";
  const AMBIENTE_EJECUCION_DESARROLLO = "Desarrollo";
  const AMBIENTE_EJECUCION_PRODUCCION = "Produccion";
  //estilo mensaje
  const ESTILO_MENSAJE_ERROR = "Error";
  const ESTILO_MENSAJE_ADVERTENCIA = "Advertencia";
  const ESTILO_MENSAJE_EXITO = "Exito";
  //nombre claves parameters
  const PARAMETERS_NOMBRE_SITIO = "nombreSitio";
  //unidades de medida byte
  const UNIDAD_BYTES = 1;
  const UNIDAD_KILOBYTES = 2;
  const UNIDAD_MEGABYTES = 3;
  const UNIDAD_GIGABYTES = 4;
  const UNIDAD_TERABYTES = 5;
  //color fondo filas datagrid
  const COLOR_FONDO_FILA_NORMAL_GRIS_DATAGRID = "#f6f6f6";
  const COLOR_FONDO_FILA_DESTACADO_VERDE_DATAGRID = "#7cfc00";
  const COLOR_FONDO_FILA_DESTACADO_ROJO_DATAGRID = "#ec6466";
  const COLOR_FONDO_FILA_DESTACADO_AMARILLO_DATAGRID = "#fdf884";
  //encriptar numeros
  const NUMERO_ENCRIPTAR = 0;
  const NUMERO_DESENCRIPTAR = 1;
  //comparar array
  const COMPARAR_ARRAY_EXACTO = 0;
  const COMPARAR_ARRAY_CONTENIDO = 1;
  //urldecode array
  const ARRAY_URL_DECODE = 0;
  const ARRAY_URL_ENCODE = 1;
  //queryString flujo
  const QUERYSTRING_FLUJO_NORMAL = "QueryStringFlujoNormal";
  const QUERYSTRING_FLUJO_MINIMO = "QueryStringFlujoMinimo";
  //unidad medida tiempo
  const UNIDAD_MEDIDA_DIA = "Day";
  const UNIDAD_MEDIDA_HORA = "Hour";
  const UNIDAD_MEDIDA_MINUTO = "Minute";
  //sufijo sesion filtros
  const SESION_SUFIJO_FILTROS = "_filtros";
  const SESION_CARGAR_FILTROS_SESION = "CargarFiltrosSesion";
  //marcos
  const MARCO_TIPO_NONE = "None";
  const MARCO_TIPO_NORMAL = "Normal";
  const MARCO_TIPO_LINEA = "Linea";
  const MARCO_TIPO_LINEA_AZUL = "Linea-Azul";
  const MARCO_POSICION_TOP = "Top";
  const MARCO_POSICION_BOTTOM = "Bottom";
  const MARCO_CSS_TITULO = "cssSubLegend";

//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Metodos Compartidos">
  /**
   * determina si un valor es nulo o vacio
   * @param <type> $valor
   * @return boolean
   * @author VSR, 01/01/2011
   */
  public static function isNullOrEmpty($valor) {
    $esNulo = false;
    try {
      if (empty($valor) || is_null($valor)) {
        $esNulo = true;
      }
    } catch (Exception $e) {
      $esNulo = false;
    }
    return $esNulo;
  }

  /**
   * obtiene el ambiente de ejecucio del sitio
   * @return string
   * @author VSR, 01/01/2011
   */
  public static function obtenerAmbienteEjecucion() {
    $ambiente = "";
    try {
      $ambiente = Configuracion::leer("ambienteEjecucion");
      $ambiente = (self::isNullOrEmpty($ambiente)) ? "INDEFINIDO" : strtoupper($ambiente);

      if ($ambiente == "PRODUCCION" || $ambiente == "PRODUCCIÓN") {
        $ambiente = "PRODUCCION";
      }
    } catch (Exception $e) {
      $ambiente = "";
    }
    return $ambiente;
  }

  /**
   * obtiene el ambiente de ejecucio del sitio
   * @return string
   * @author VSR, 01/01/2011
   */
  public static function pais() {
    $texto = "";
    try {
      $texto = Configuracion::leer("pais");
    } catch (Exception $e) {
      $texto = "";
    }
    return $texto;
  }

  /**
   * obtiene el modo de ejecucion del sitio
   * @return string
   * @author VSR, 31/10/2011
   */
  public static function modoDebug() {
    $texto = false;
    try {
      $texto = Configuracion::leer("modoDebug");
      if (strtolower($texto) == "true") {
        $texto = true;
      } else {
        $texto = false;
      }
    } catch (Exception $e) {
      $texto = false;
    }
    return $texto;
  }

  /**
   * obtiene el email para las pruebas
   * @return string
   * @author VSR, 31/10/2011
   */
  public static function emailPruebas() {
    $texto = "";
    try {
      $texto = Configuracion::leer("mailPruebas");
    } catch (Exception $e) {
      $texto = "";
    }
    return $texto;
  }

  /**
   * obtiene el email de los administradores
   * @return string
   * @author VSR, 31/10/2011
   */
  public static function emailAdministrador() {
    $texto = "";
    try {
      $texto = Configuracion::leer("mailAdministrador");
    } catch (Exception $e) {
      $texto = "";
    }
    return $texto;
  }

  /**
   * inicializa en session los datos del usuario
   * @param <type> $oUsuario
   * @author VSR, 01/01/2011
   */
  public static function inicializarSesion($oUsuario) {
    try {
      $oPerfil = new Perfil($oUsuario->getIdPerfil());
      $session = new THttpSession;
      $session->open();
      $totalSesiones = $session->count();
      if ($totalSesiones > 0) {
        $session->clear();
      }
      $oUsuario->setPerfilLlave($oPerfil->getLlave());
      $oUsuario->setPerfilNombre($oPerfil->getNombre());
      $session[Usuario::NOMBRE_ENTIDAD] = $oUsuario;
      $session[Pagina::SESION_PAGINA_INICIO] = Configuracion::leer("paginaInicio");

      //actualizamos algunos datos del usuario
      $oUsuario->setFechaHoraUltimoAcceso(self::obtenerFechaHoraDATETIME());
      $oUsuario->grabar();
    } catch (Exception $e) {
      throw new Exception($e->getMessage());
    }
  }

  /**
   * retorna la fecha actual en formato ISO: yyyymmddhhmmss
   * @author VSR, 01/01/2011
   */
  public static function obtenerFechaHoraISO() {
    date_default_timezone_set(self::ZONA_HORARIA);
    $fecha = date("YmdHis");
    return $fecha;
  }

  /**
   * retorna la fecha actual en formato DATETIME: yyyy-mm-dd hh:mm:ss
   * @author VSR, 01/01/2011
   */
  public static function obtenerFechaHoraDATETIME() {
    date_default_timezone_set(self::ZONA_HORARIA);
    $fecha = date("Y-m-d H:i:s");
    return $fecha;
  }

  /**
   * retorna la fecha actual en formato DDMMAAAA: dd/mm/yyyy hh:mm:ss
   * @author VSR, 01/01/2011
   */
  public static function obtenerFechaHoraDDMMAAAA($mostrarHora = false) {
    date_default_timezone_set(self::ZONA_HORARIA);
    if ($mostrarHora) {
      $fecha = date("d/m/Y H:i:s")." hrs.";
    } else {
      $fecha = date("d/m/Y");
    }
    return $fecha;
  }


  /**
   * retorna la fecha actual en formato ISO: yyyymmdd
   * @author VSR, 01/01/2011
   */
  public static function obtenerFechaISO() {
    $fechaISO = self::obtenerFechaHoraISO();
    return self::left($fechaISO, 8);
  }

  /**
   * retorna la hora actual en formato ISO: hhmmss
   * @author VSR, 01/01/2011
   */
  public static function obtenerHoraISO() {
    $fechaISO = self::obtenerFechaHoraISO();
    return self::right($fechaISO, 6);
  }

  /**
   * obtiene n caracteres del lado izquierdo del texto
   * @param <type> $string
   * @param <type> $count
   * @return <type>
   * @author VSR, 01/01/2011
   */
  public static function left($string, $count) {
    $string = substr($string, 0, $count);
    return $string;
  }

  /**
   * obtiene n caracteres del lado derecho del texto
   * @param <type> $string
   * @param <type> $count
   * @return <type>
   * @author VSR, 01/01/2011
   */
  public static function right($string, $count) {
    $string = substr($string, -$count, $count);
    return $string;
  }

  /**
   * filtra los registros de un arreglo, con condiciones enviadas en formato JSON
   * @param <type> $arr
   * @param <type> $condicionJSON
   * @example $arrFiltrado = Utilidades::arrayRowFilterJSON($array[1],'[{"campo":"Modulo", "condicion":"== \'Usuario\'"}, {"campo":"&& NombreClase", "condicion":"== \'AdmListado\'"}]');
   * @author VSR, 01/01/2011
   */
  public static function arrayRowFilterJSON($array, $condicionJSON) {
    $newArray = array();
    $filtroCompleto = "";
    try {
      if (self::isNullOrEmpty($condicionJSON) || !is_array($array)) {
        $newArray = $array;
      } else {
        $arrCondicion = json_decode($condicionJSON, true);
        //construye el formato de la condicion
        for ($i = 0; $i <= count($arrCondicion) - 1; $i++) {
          $campo = $arrCondicion[$i]["campo"];
          $condicion = $arrCondicion[$i]["condicion"];

          //formatea valor del campo
          if (self::startsWith($campo, "&&")) {
            $campo = trim(str_replace("&&", "", $campo));
            $campo = "&& #array[#i][\"$campo\"]";
          } elseif (self::startsWith($campo, "||")) {
            $campo = trim(str_replace("||", "", $campo));
            $campo = "|| #array[#i][\"$campo\"]";
          } else {
            $campo = "#array[#i][\"$campo\"]";
          }

          //construye el filtro completo para el IF
          $filtroCompleto = $filtroCompleto . $campo . " " . $condicion . " ";
        }
        //reemplaza marcas especiales
        $expresion = "if( $filtroCompleto ){ #newArray[] = #array[#i]; } ";
        $expresion = str_replace("#", "$", $expresion);
        for ($i = 0; $i <= count($array) - 1; $i++) {
          //evalua la expresion y si encuentra alguna coincidencia almacena
          //la fila encontrada en el newArray
          eval($expresion);
        }
      }
      return $newArray;
    } catch (Exception $e) {
      throw new Exception($e->getMessage());
    }
  }

  /**
   * filtra los registros de un arreglo, condiciones enviadas como las de un IF normal
   * @param <type> $arr
   * @param <type> $condicion
   * @example $arrFiltrado = Utilidades::arrayRowFilter($array[1],"Modulo == 'Pagina' && (TituloPagina == 'Paginas' && (IdPagina == 3 || IdPagina != 1)) ");
   * @author VSR, 01/01/2011
   */
  public static function arrayRowFilter($array, $condicion) {
    $newArray = array();
    $filtroCompleto = "";
    $listadoCamposReemplazados = "";
    try {
      if (self::isNullOrEmpty($condicion) || !is_array($array)) {
        $newArray = $array;
      } else {
        //reemplaza todos los conectores logicos(&&, ||) por @, para despues hacer un explode por ese caracter
        $condicionAuxiliar = str_replace("&&", "@", $condicion);
        $condicionAuxiliar = str_replace("||", "@", $condicionAuxiliar);
        $arrCondicion = explode("@", $condicionAuxiliar);

        //construye el formato de la condicion
        for ($i = 0; $i <= count($arrCondicion) - 1; $i++) {
          $condicionSinCambio = trim($arrCondicion[$i]);
          //reemplaza todos los conectores de comparacion(==, !=) por @, para despues hacer un explode por ese caracter
          $condicionAuxiliar = str_replace("==", "@", $condicionSinCambio);
          $condicionAuxiliar = str_replace("!=", "@", $condicionAuxiliar);
          $arrCondicionAuxiliar = explode("@", $condicionAuxiliar);
          $campo = trim(str_replace("(", "", $arrCondicionAuxiliar[0]));
          //verifica si el campo no fue reemplazado, y si no lo ha sido entonces lo cambia en la condicion
          //general y agrega el campo a la lista
          $pos = strpos($listadoCamposReemplazados, strtoupper("[$campo]"));
          if ($pos === false) {
            //reemplaza el campo original de la condicion por el del arreglo
            $condicion = preg_replace("/\b" . $campo . "\b/", " #array[#i][\"$campo\"]", $condicion);
            $listadoCamposReemplazados = $listadoCamposReemplazados . strtoupper("[$campo]");
          }
        }
        //reemplaza marcas especiales
        $expresion = "if( $condicion ){ #newArray[] = #array[#i]; } ";
        $expresion = str_replace("#", "$", $expresion);
        $expresion = str_replace("'", "\"", $expresion);
        for ($i = 0; $i <= count($array) - 1; $i++) {
          //evalua la expresion y si encuentra alguna coincidencia almacena la fila encontrada en el newArray
          eval($expresion);
        }
      }
      return $newArray;
    } catch (Exception $e) {
      throw new Exception($e->getMessage());
    }
  }

  /**
   * determina si un texto comienza con una palabra especifica
   * @param <type> $textoOriginal
   * @param <type> $textoABuscar
   * @return <type>
   * @author VSR, 01/01/2011
   */
  public static function startsWith($textoOriginal, $textoABuscar) {
    return strpos($textoOriginal, $textoABuscar) === 0;
  }

  /**
   * graba un objeto en sesion
   * @param <type> $nombreSesion
   * @param <type> $obj
   * @author VSR, 01/01/2011
   */
  public static function grabarSessionPorNombre($nombreSesion, $obj) {
    try {
      $session = new THttpSession;
      $session[$nombreSesion] = $obj;
    } catch (Exception $e) {
      $session[$nombreSesion] = null;
    }
  }

  /**
   * obtiene el valor de la session por el nombre
   * @param <type> $nombreSesion
   * @return string
   * @author VSR, 01/01/2011
   */
  public static function obtenerSessionPorNombre($nombreSesion) {
    $obj = null;
    try {
      $session = new THttpSession();
      $obj = $session[$nombreSesion];
    } catch (Exception $e) {
      $obj = null;
    }
    return $obj;
  }

  /**
   * obtiene nombre del directorio base donde corre la aplicacion
   * @author VSR, 01/01/2011
   */
  public static function obtenerDirectorioBaseAplicacion() {
    $directorio = dirname(Prado::getApplication()->getBasePath());
    return $directorio . DIRECTORY_SEPARATOR;
  }

  /**
   * obtiene nombre del directorio vitual del sistema
   * @return <type>
   * @author VSR, 30/10/2011
   */
  public static function obtenerDirectorioVirtual() {
    $response = new THttpRequest;
    return $response->getBaseUrl();
  }

  /**
   * obtiene el contenido de un archivo de texto
   * @param <type> $rutaPlantilla
   * @param <type> $quitarEspaciosBlancos
   * @return string
   * @author VSR, 01/01/2011
   */
  public static function obtenerContenidoPlantillaHTML($rutaPlantilla, $quitarEspaciosBlancos = false, $guardarEnSession = true) {
    $plantilla = null;
    $html = "";

    try {
      if($guardarEnSession) {
        $plantilla = self::obtenerSessionPorNombre($rutaPlantilla);
      }
      
      if (is_null($plantilla)) {
        $sb = new StringBuilder();
        if (Archivo::existeArchivo($rutaPlantilla)) {
          $archivo = file($rutaPlantilla);
          $totalLineas = count($archivo);
          for ($i = 0; $i < $totalLineas; $i++) {
            $linea = $archivo[$i];
            if ($quitarEspaciosBlancos) {
              if (!self::isNullOrEmpty($linea)) {
                $sb->append(trim($linea));
              }
            } else {
              $sb->append($linea);
            }
          }
          $plantilla = $sb->toString();
          if($guardarEnSession) {
            self::grabarSessionPorNombre($rutaPlantilla, $plantilla);
          }
          unset($archivo);
        } else {
          $plantilla = "";
        }
      }
    } catch (Exception $e) {
      $plantilla = "";
    }
    return $plantilla;
  }

  /**
   * extrae el texto de una cadena entre dos palabras dadas
   * @param <type> $texto
   * @param <type> $palabraInicial
   * @param <type> $palabraFinal
   * @author VSR, 01/01/2011
   */
  public static function extraeTextoEntreDosPalabras($texto, $palabraInicial, $palabraFinal) {
    $textoExtraido = "";
    try {
      if (!self::isNullOrEmpty($texto)) {
        $inicio = strpos($texto, $palabraInicial, 1) + strlen($palabraInicial);
        $fin = strpos($texto, $palabraFinal, $inicio);
        if ($fin > 0 && $inicio > strlen($palabraInicial)) {
          $textoExtraido = trim(str_replace("\r\n", "", (substr($texto, $inicio, $fin - $inicio))));
        }
      }
    } catch (Exception $e) {
      $textoExtraido = $texto;
    }
    //retorna valor
    return $textoExtraido;
  }

  /**
   * determina si tiene permiso sobre la funcion de la pagina consultada
   * @param <type> $nombrePagina
   * @param <type> $nombreFuncion
   * @return boolean
   * @author VSR, 01/01/2011
   */
  public static function tienePermiso($nombrePagina, $nombreFuncion) {
    $existePermiso = false;

    try {
      $oUsuario = self::obtenerSessionPorNombre(Usuario::NOMBRE_ENTIDAD);
      $arrPermisos = Utilidades::obtenerSessionPorNombre(Usuario::SESION_MATRIZ_PERMISO);

      if ($oUsuario->getEsSuper()) {
        $existePermiso = true;
      } else {
        if (!is_null($arrPermisos)) {
          $arrFila = self::arrayRowFilter($arrPermisos[Usuario::ARRAY_PERMISO_LISTADO_FUNCIONES], "(NombreClase == '" . $nombrePagina . "' || ModuloNombreClase == '" . $nombrePagina . "') && LlaveIdentificador == '" . $nombreFuncion . "'");
          $totalFilas = count($arrFila);
          $existePermiso = ($totalFilas > 0) ? true : false;
        }
      }
    } catch (Exception $e) {
      $existePermiso = false;
    }
    return $existePermiso;
  }

  /**
   * reemplaza un valor nulo por un valor de reemplazo
   * @param <type> $valorActual
   * @param <type> $valorReemplazo
   * @author VSR, 01/01/2011
   */
  public static function isNull($valorActual, $valorReemplazo) {
    if (self::isNullOrEmpty($valorActual)) {
      return $valorReemplazo;
    } else {
      return $valorActual;
    }
  }

  /**
   * obtiene el numero de registros por pagina definidos por defecto en el application.xml
   * @author VSR, 01/01/2011
   */
  public static function obtenerRegistrosPorPaginaDefault($application) {
    $parameters = $application->Parameters;
    $valor = $parameters["registrosPorPagina"];
    return $valor;
  }

  /**
   * obtiene el valor del parameters de application.xml usando la clave
   * @author VSR, 01/01/2011
   */
  public static function obtenerValorParameters($application, $clave) {
    $parameters = $application->Parameters;
    $valor = $parameters[$clave];
    return $valor;
  }

  /**
   * obtiene el nombre del host smpt para el envio de correo
   * @author VSR, 16/04/2011
   */
  public static function emailHost($application) {
    return self::obtenerValorParameters($application, "emailHost");
  }

  /**
   * obtiene el username del correo desde el cual se envia
   * @author VSR, 16/04/2011
   */
  public static function emailUsername($application) {
    return self::obtenerValorParameters($application, "emailUsername");
  }

  /**
   * obtiene el password del correo desde el cual se envia
   * @author VSR, 16/04/2011
   */
  public static function emailPassword($application) {
    return Criptografia::desencriptar(self::obtenerValorParameters($application, "emailPassword"));
  }

  /**
   * obtiene el nombre del emisor del correo
   * @author VSR, 16/04/2011
   */
  public static function emailNombreEmisor($application) {
    return self::obtenerValorParameters($application, "emailNombreEmisor");
  }

  /**
   * ordena un array por un campo cualquiera de manera ascendente o descendente
   * @param <type> $arrayOrdenar
   * @param <type> $nombreCampo
   * @param <type> $descendente
   * @return <type>
   * @author VSR, 01/01/2011
   */
  public static function ordenarMultiDimensionalArray($arrayOrdenar, $nombreCampo, $ascendente = true) {
    $position = array();
    $newRow = array();
    foreach ($arrayOrdenar as $key => $row) {
      $position[$key] = $row[$nombreCampo];
      $newRow[$key] = $row;
    }
    if ($ascendente) {
      asort($position);
    } else {
      arsort($position);
    }
    $returnArray = array();
    foreach ($position as $key => $pos) {
      $returnArray[] = $newRow[$key];
    }
    return $returnArray;
  }

  /**
   * ordena el array por el campo seleccionado y determina si tiene que hacerlo de manera ascendente o descendente
   * @param <type> $arrayOrdenar
   * @param <type> $campoOrdenActual
   * @param <type> $campoOrdenSeleccionado
   * @author VSR, 01/01/2011
   */
  public static function obtenerSortArray($arrayOrdenar, &$campoOrdenActual, $campoOrdenSeleccionado) {
    $newArray = null;
    $nombreCampo = "";
    $textoOrden = "";

    try {
      if (self::isNullOrEmpty($campoOrdenActual)) {
        $nombreCampo = $campoOrdenSeleccionado;
        $campoOrdenActual = $nombreCampo . ";ASC";
        $ordenAscendente = true;
      } else {
        $arrCampoOrdenActual = explode(";", $campoOrdenActual);
        $nombreCampo = $arrCampoOrdenActual[0];
        $textoOrden = $arrCampoOrdenActual[1];
        //si se esta ordenando por el mismo campo entonces se verifica si se tiene que hacer de manera
        //ascendente o descendente
        if ($nombreCampo == $campoOrdenSeleccionado) {
          if ($textoOrden == "ASC") {
            $campoOrdenActual = $nombreCampo . ";DESC";
            $ordenAscendente = false;
          } else {
            $campoOrdenActual = $nombreCampo . ";ASC";
            $ordenAscendente = true;
          }
        } else {
          $nombreCampo = $campoOrdenSeleccionado;
          $campoOrdenActual = $nombreCampo . ";ASC";
          $ordenAscendente = true;
        }
      }
      //ordena el array
      $newArray = self::ordenarMultiDimensionalArray($arrayOrdenar, $nombreCampo, $ordenAscendente);
    } catch (Exception $e) {
      $newArray = $arrayOrdenar;
    }
    return $newArray;
  }

  /**
   * configura el paginador del DataGrid
   * @param <type> $pagerStyle
   * @param <type> $totalRegistros
   * @param <type> $pageSize
   * @author VSR, 01/01/2011
   */
  public static function configurarPaginadorDataGrid($pagerStyle, $totalRegistros, $pageSize) {
    $mostrarPaginador = ($totalRegistros > $pageSize);
    $pagerStyle->Visible = $mostrarPaginador;
    $pagerStyle->Mode = 'Numeric';
    $pagerStyle->NextPageText = "&gt;&gt;";
    $pagerStyle->PrevPageText = "&lt;&lt;";
    $pagerStyle->PageButtonCount = 10;
    $pagerStyle->HorizontalAlign = "Center";
    $pagerStyle->CssClass = "cssPaginador";
    if ($pageSize > 50) {
      $pagerStyle->Position = "TopAndBottom";
    } else {
      $pagerStyle->Position = "Bottom";
    }
  }

  /**
   * construye mensaje en la pantalla
   * @param <type> $panel
   * @param <type> $textoMensaje
   * @param <type> $porcentajeAnchoMensaje
   * @param <type> $estiloMensaje
   * @author VSR, 01/01/2011
   */
  public static function setPanelMensajeUsuario($panel, $textoMensaje, $porcentajeAnchoMensaje, $estiloMensaje) {
    if (!self::isNullOrEmpty($textoMensaje)) {
      $sb = new StringBuilder();
      $lblMensaje = new TLabel();

      switch ($estiloMensaje) {
        case self::ESTILO_MENSAJE_ERROR :
          $estiloMarco = "cssDestacadoMsgError";
          $estiloTexto = "cssMensajeError";
          break;
        case self::ESTILO_MENSAJE_ADVERTENCIA :
          $estiloMarco = "cssDestacadoMsgAdvertencia";
          $estiloTexto = "cssMensajeAdvertenciaBloque";
          break;
        default:
          $estiloMarco = "cssDestacadoMsgExito";
          $estiloTexto = "cssMensajeExito";
          break;
      }
      $porcentajeAnchoMensaje = (self::isNullOrEmpty($porcentajeAnchoMensaje)) ? "50%" : $porcentajeAnchoMensaje;
      $estiloMensaje = (self::isNullOrEmpty($estiloMensaje)) ? "Exito" : $estiloMensaje;

      $sb->appendLine("<div class=\"clearBoth\">");
      $sb->appendLine("  <center>");
      $sb->appendLine("    <ul style=\"width:" . $porcentajeAnchoMensaje . ";text-align:center;\">");
      $sb->appendLine("      <li class=\"" . $estiloMarco . "\"><span class=\"" . $estiloTexto . " cssMensajeUsuario\">" . $textoMensaje . "</span></li>");
      $sb->appendLine("    </ul>");
      $sb->appendLine("  </center>");
      $sb->appendLine("</div>");

      $lblMensaje->Text = $sb->toString();
      $panel->Controls->Add($lblMensaje);
      $panel->HorizontalAlign = "Center";
    }
  }

  /**
   * construye mensaje en la pantalla con un boton cerrar
   * @param <type> $panel
   * @param <type> $textoMensaje
   * @param <type> $porcentajeAnchoMensaje
   * @param <type> $estiloMensaje
   * @author VSR, 01/01/2011
   */
  public static function setPanelMensajeUsuarioConBotonCerrar($panel, $textoMensaje, $porcentajeAnchoMensaje, $estiloMensaje, $baseUrl) {
    if (!self::isNullOrEmpty($textoMensaje)) {
      $sb = new StringBuilder();
      $lblMensaje = new TLabel();

      switch ($estiloMensaje) {
        case self::ESTILO_MENSAJE_ERROR :
          $estiloMarco = "cssDestacadoMsgError";
          $estiloTexto = "cssMensajeError";
          $iconoCerrar = "ico16-cerrar-rojo";
          break;
        case self::ESTILO_MENSAJE_ADVERTENCIA :
          $estiloMarco = "cssDestacadoMsgAdvertencia";
          $estiloTexto = "cssMensajeAdvertenciaBloque";
          $iconoCerrar = "ico16-cerrar-amarillo";
          break;
        default:
          $estiloMarco = "cssDestacadoMsgExito";
          $estiloTexto = "cssMensajeExito";
          $iconoCerrar = "ico16-cerrar-verde";
          break;
      }
      $porcentajeAnchoMensaje = (self::isNullOrEmpty($porcentajeAnchoMensaje)) ? "50%" : $porcentajeAnchoMensaje;
      $estiloMensaje = (self::isNullOrEmpty($estiloMensaje)) ? "Exito" : $estiloMensaje;

      $sb->appendLine("<div class=\"clearBoth\">");
      $sb->appendLine("  <div class=\"clearBoth\">");
      $sb->appendLine("    <center>");
      $sb->appendLine("      <ul style=\"width:" . $porcentajeAnchoMensaje . ";text-align:center;\">");
      $sb->appendLine("        <li class=\"" . $estiloMarco . "\">");
      $sb->appendLine("        <table border=\"0\" cellpadding=\"0\" cellspacing=\"\" width=\"100%\">");
      $sb->appendLine("          <tr valign=\"top\">");
      $sb->appendLine("            <td><div class=\"clearBoth " . $estiloTexto . " cssMensajeUsuario\">" . $textoMensaje . "</div></td>");
      $sb->appendLine("            <td style=\"width:13px\"><div class=\"clearBoth cssTextoNormalBlack\"><span><a href=\"javascript:;\" onclick=\"ocultarElemento('" . $panel->ClientID . "');\"><span class=\"" . $iconoCerrar . " cursorPointer\"><img src=\"" . $baseUrl . "/img/_blank.gif\" class=\"ico16Cerrar\" alt=\"\" /></span></a></span></div></td>");
      $sb->appendLine("          </tr>");
      $sb->appendLine("        </table>");
      $sb->appendLine("        </li>");
      $sb->appendLine("      </ul>");
      $sb->appendLine("    </center>");
      $sb->appendLine("  </div>");
      $sb->appendLine("</div>");

      $lblMensaje->Text = $sb->toString();
      $panel->Controls->Add($lblMensaje);
      $panel->HorizontalAlign = "Center";
    }
  }

  /**
   * obtiene el indice de la primera fila de la grilla dependiendo en que pagina este
   * @param <type> $datagrid
   * @return <type>
   * @author VSR, 01/01/2011
   */
  public static function obtenerIndicePrimeraFilaGrilla($datagrid) {
    //obtiene valor actual de la pagina de la grilla
    $indicePaginaInicio = $datagrid->CurrentPageIndex + 1;
    //obtiene el numero de registros por pagina de la grilla
    $numeroRegistrosPorPagina = $datagrid->PageSize;
    //calcula cual es el valor del indice de la primera fila de la grilla
    $indicePrimeraFila = $indicePaginaInicio * $numeroRegistrosPorPagina - ($numeroRegistrosPorPagina - 1);
    //retorna valor
    return $indicePrimeraFila;
  }

  /**
   * asigna valor del indice de la fila al control
   * @param <type> $item
   * @param <type> $nombreControlIndiceFila
   * @param <type> $indiceFila
   * @author VSR, 01/01/2011
   */
  public static function setControlIndiceFila($item, $nombreControlIndiceFila, $indiceFila) {
    $lblIndiceFila = $item->findControl($nombreControlIndiceFila);
    $lblIndiceFila->Text = $indiceFila;
  }

  /**
   * muestra el total de registros de una grilla
   * @param <type> $totalRegistros
   * @param <type> $label
   * @param <type> $nombreElementoContar
   * @author VSR, 01/01/2011
   */
  public static function mostrarTotalRegistrosGrilla($totalRegistros, $label, $nombreElementoContar = "Registros") {
    $textoSugerencia = "";

    if ($totalRegistros == 500) {
      $textoSugerencia = "&nbsp;o m&aacute;s";
    }

    $label->Visible = true;
    $label->Text = "Total de " . $nombreElementoContar . ": " . $totalRegistros . $textoSugerencia;
  }

  /**
   * obtiene nombre de la pagina actual ejecutada
   * @param <type> $obj
   * @return <type>
   * @author VSR, 01/01/2011
   */
  public static function obtenerNombrePaginaActual($obj) {
    $paginaActual = $obj->getPage()->getPagePath();
    return $paginaActual;
  }

  /**
   * escapar comillas enrutinas JS
   * @param <type> $texto
   * @return <type>
   * @author VSR, 01/01/2011
   */
  public static function escaparComillasJS($texto) {
    //cambio los \n por ~~ (esto es necesario, pues a continuacion voy a sacar los "\" para que no puedan dañar)
    $texto = str_replace("\n", "~~", $texto);
    //escapa el caracter de escape
    $texto = str_replace("\\", "\\\\", $texto);
    //escapa comillas simples
    $texto = str_replace("'", "\'", $texto);
    //escapa comillas dobles
    $texto = str_replace("\"", "\042", $texto);
    //cambia ~~ por \n
    $texto = str_replace("~~", "\n", $texto);

    return trim($texto);
  }

  /**
   * convierte una unidad de medida en otra
   * @param <type> $tamano
   * @param <type> $aproximarMedidaMasCercana
   * @param <type> $cantidadDecimales
   * @param <type> $unidadMedidaOrigen
   * @param <type> $unidadMedidaDestino
   * @return <type>
   * @author VSR, 22/04/2011
   */
  public static function convertirUnidadMedidaArchivo($tamano, $aproximarMedidaMasCercana, $cantidadDecimales = 2, $unidadMedidaOrigen = self::UNIDAD_BYTES, $unidadMedidaDestino = self::UNIDAD_KILOBYTES) {
    $UNIDAD_BASE = 1024;
    $BYTES = 1;
    $KB_EN_BYTES = pow($UNIDAD_BASE, 1);
    $MB_EN_BYTES = pow($UNIDAD_BASE, 2);
    $GB_EN_BYTES = pow($UNIDAD_BASE, 3);
    $TB_EN_BYTES = pow($UNIDAD_BASE, 4);
    $dividendo = 0;
    $divisor = 1;
    $valor = 0;
    $retorno = "";
    $unidadMedida = "";

    //transforma el valor original en bytes
    switch ($unidadMedidaOrigen) {
      case self::UNIDAD_BYTES:
        $dividendo = $tamano * $BYTES;
        break;
      case self::UNIDAD_KILOBYTES:
        $dividendo = $tamano * $KB_EN_BYTES;
        break;
      case self::UNIDAD_MEGABYTES:
        $dividendo = $tamano * $MB_EN_BYTES;
        break;
      case self::UNIDAD_GIGABYTES:
        $dividendo = $tamano * $GB_EN_BYTES;
        break;
      case self::UNIDAD_TERABYTES:
        $dividendo = $tamano * $TB_EN_BYTES;
        break;
      default:
        $dividendo = $tamano * $KB_EN_BYTES;
        break;
    }

    //determina en que unidad se va a convertir
    switch ($unidadMedidaDestino) {
      case self::UNIDAD_BYTES:
        $divisor = $BYTES;
        $unidadMedida = "bytes";
        break;
      case self::UNIDAD_KILOBYTES:
        $divisor = $KB_EN_BYTES;
        $unidadMedida = "Kb";
        break;
      case self::UNIDAD_MEGABYTES:
        $divisor = $MB_EN_BYTES;
        $unidadMedida = "Mb";
        break;
      case self::UNIDAD_GIGABYTES:
        $divisor = $GB_EN_BYTES;
        $unidadMedida = "Gb";
        break;
      case self::UNIDAD_TERABYTES:
        $divisor = $TB_EN_BYTES;
        $unidadMedida = "Tb";
        break;
      default:
        $divisor = $KB_EN_BYTES;
        $unidadMedida = "Kb";
        break;
    }

    //calcula el valor
    $valor = round($dividendo / $divisor, $cantidadDecimales);
    $retorno = $valor . " " . $unidadMedida;

    //si se aproxima a la unidad mas cercana entonces se calcula de nuevo
    if ($aproximarMedidaMasCercana) {
      if ($dividendo < $KB_EN_BYTES) {
        $retorno = self::convertirUnidadMedidaArchivo($dividendo, false, $cantidadDecimales, self::UNIDAD_BYTES, self::UNIDAD_BYTES);
      } elseif ($dividendo >= $KB_EN_BYTES && $dividendo < $MB_EN_BYTES) {
        $retorno = self::convertirUnidadMedidaArchivo($dividendo, false, $cantidadDecimales, self::UNIDAD_BYTES, self::UNIDAD_KILOBYTES);
      } elseif ($dividendo >= $MB_EN_BYTES && $dividendo < $GB_EN_BYTES) {
        $retorno = self::convertirUnidadMedidaArchivo($dividendo, false, $cantidadDecimales, self::UNIDAD_BYTES, self::UNIDAD_MEGABYTES);
      } elseif ($dividendo >= $GB_EN_BYTES && $dividendo < $TB_EN_BYTES) {
        $retorno = self::convertirUnidadMedidaArchivo($dividendo, false, $cantidadDecimales, self::UNIDAD_BYTES, self::UNIDAD_GIGABYTES);
      } elseif ($dividendo >= $TB_EN_BYTES) {
        $retorno = self::convertirUnidadMedidaArchivo($dividendo, false, $cantidadDecimales, self::UNIDAD_BYTES, self::UNIDAD_TERABYTES);
      }
    }
    //retorna valor
    return str_replace(".", ",", $retorno);
  }

  /**
   * muestra u oculta una columna de la grilla segun el indice de la columna
   * @param <type> $dataGrid
   * @param <type> $indiceColumna
   * @param <type> $esVisible
   * @author VSR, 24,04/2011
   */
  public static function visibleColumnaGrillaPorIndiceColumna($dataGrid, $indiceColumna, $esVisible) {
    $dataGrid->Columns[$indiceColumna]->Visible = $esVisible;
  }

  /**
   * obtiene la ruta de la imagen
   * @param <type> $extension
   * @param <type> $contentType
   * @param <type> $themeBaseUrl
   * @return <type> 
   * @author VSR, 29/04/2011
   */
  public static function obtenerRutaIconoTipoArchivo($extension, $contentType, $themeBaseUrl) {
    $sourceIcono = "";
    try {
      $iconoAsociado = self::obtenerIconoTipoArchivo($extension, $contentType);
      //construye ruta
      $sourceIcono = "<span class=\"ico16-$iconoAsociado\"><img src=\"$themeBaseUrl/img/_blank.gif\" class=\"ico16\" alt=\"$contentType\" /></span>";
    } catch (Exception $e) {
      $sourceIcono = "";
    }
    //retorna valor
    return $sourceIcono;
  }

  /**
   * obtiene un icono asociado al tipo de archivo
   * @param <type> $extension
   * @param <type> $contentType
   * @return string
   * @author VSR, 29/04/2011
   */
  public static function obtenerIconoTipoArchivo($extension, $contentType) {
    $iconoAplicacion = "aplicacion";
    $iconoAudio = "audio";
    $iconoBlank = "blank";
    $iconoExcel = "excel";
    $iconoImage = "image";
    $iconoOffice = "office";
    $iconoOtro = "otro";
    $iconoPDF = "pdf";
    $iconoPPT = "ppt";
    $iconoText = "txt";
    $iconoVideo = "video";
    $iconoWord = "word";
    $iconoZip = "zip";
    $iconoAsociado = "";
    $buscarUsandoContentType = false;

    //primero busca en las extensiones mas usadas
    switch (strtolower($extension)) {
      case "pdf":
        $iconoAsociado = $iconoPDF;
        break;
      case "doc":
      case "docx":
      case "rtf":
        $iconoAsociado = $iconoWord;
        break;
      case "xls":
      case "xlsx":
        $iconoAsociado = $iconoExcel;
        break;
      case "pps":
      case "ppt":
      case "pptx":
        $iconoAsociado = $iconoPPT;
        break;
      case "txt":
        $iconoAsociado = $iconoText;
        break;
      case "zip":
      case "rar":
        $iconoAsociado = $iconoZip;
        break;
      case "mp3":
      case "wav":
      case "wma":
        $iconoAsociado = $iconoAudio;
        break;
      default:
        $buscarUsandoContentType = true;
        break;
    }

    //si no encuentra el icono en las extension conocidas busca en los iconos
    //asociados al contentType
    if ($buscarUsandoContentType) {
      $tipoArchivo = Archivo::esTipoArchivo($contentType);
      switch ($tipoArchivo) {
        case Archivo::TIPO_APLICACION:
          $iconoAsociado = $iconoAplicacion;
          break;
        case Archivo::TIPO_AUDIO:
          $iconoAsociado = $iconoAudio;
          break;
        case Archivo::TIPO_DESCONOCIDO:
          $iconoAsociado = $iconoBlank;
          break;
        case Archivo::TIPO_IMAGEN:
          $iconoAsociado = $iconoImage;
          break;
        case Archivo::TIPO_OFFICE:
          $iconoAsociado = $iconoOffice;
          break;
        case Archivo::TIPO_OTRO:
          $iconoAsociado = $iconoOtro;
          break;
        case Archivo::TIPO_TEXTO:
          $iconoAsociado = $iconoText;
          break;
        case Archivo::TIPO_VIDEO:
          $iconoAsociado = $iconoVideo;
          break;
        case Archivo::TIPO_ZIP:
          $iconoAsociado = $iconoZip;
          break;
        default:
          $iconoAsociado = $iconoBlank;
          break;
      }
    }

    //retorna valor
    return $iconoAsociado;
  }

  /**
   * reemplaza los acentos de un texto
   * @param <type> $texto
   * @return <type>
   * @author VSR, 30/04/2011
   */
  public static function reemplazarAcento($texto) {
    try {
      $texto = str_replace("á", "a", $texto);
      $texto = str_replace("é", "e", $texto);
      $texto = str_replace("í", "i", $texto);
      $texto = str_replace("ó", "o", $texto);
      $texto = str_replace("ú", "u", $texto);
      $texto = str_replace("Á", "A", $texto);
      $texto = str_replace("É", "E", $texto);
      $texto = str_replace("Í", "I", $texto);
      $texto = str_replace("Ó", "O", $texto);
      $texto = str_replace("Ú", "U", $texto);
    } catch (Exception $e) {
      $texto = $texto;
    }
    return $texto;
  }

  /**
   * formatea un numero con separador de miles
   * @param <type> $valor
   * @param <type> $cantidadDecimales
   * @return <type>
   */
  public static function formatearConSeparadorMiles($valor, $cantidadDecimales = 0) {
    $nuevoValor = "";
    try {
      //si trae puntos se los quita
      $valor = str_replace(",", ".", $valor);
      $nuevoValor = number_format($valor, $cantidadDecimales, ",", ".");
    } catch (Exception $e) {
      $nuevoValor = $valor;
    }
    return $nuevoValor;
  }

  /**
   * obtiene icono de color para el tamano total de archivos por entidad
   * @param <type> $tamano
   * @return string 
   */
  public static function obtenerIconoTamanoArchivo($tamano, $tipo, $themeBaseUrl) {
    $icono = "";
    $color = "";
    try {
      if ($tipo == "Entidad") {
        if ($tamano >= Archivo::TAMANO_ENTIDAD_VERDE && $tamano < Archivo::TAMANO_ENTIDAD_AMARILLO) {
          $color = "verde";
        } elseif ($tamano >= Archivo::TAMANO_ENTIDAD_AMARILLO && $tamano < Archivo::TAMANO_ENTIDAD_ROJO) {
          $color = "amarillo";
        } elseif ($tamano >= Archivo::TAMANO_ENTIDAD_ROJO) {
          $color = "rojo";
        } else {
          $color = "";
        }
      } else {
        if ($tamano >= Archivo::TAMANO_ARCHIVO_VERDE && $tamano < Archivo::TAMANO_ARCHIVO_AMARILLO) {
          $color = "verde";
        } elseif ($tamano >= Archivo::TAMANO_ARCHIVO_AMARILLO && $tamano < Archivo::TAMANO_ARCHIVO_ROJO) {
          $color = "amarillo";
        } elseif ($tamano >= Archivo::TAMANO_ARCHIVO_ROJO) {
          $color = "rojo";
        } else {
          $color = "";
        }
      }
      //construye ruta
      if (!Utilidades::isNullOrEmpty($color)) {
        $icono = "<span class=\"ico16-$color\"><img src=\"$themeBaseUrl/img/_blank.gif\" class=\"ico16\" alt=\"\" /></span>";
      }
    } catch (Exception $e) {
      $icono = "";
    }
    return $icono;
  }

  /**
   * configura el paginado de un datalist
   * @param <type> $arr
   * @param <type> $totalRegistros
   * @param <type> $dataList
   * @param <type> $panelPaginadorTop
   * @param <type> $panlPaginadorBottom
   * @param <type> $pagerTop
   * @param <type> $pagerBottom 
   */
  public static function configurarPaginadorDataList($arr, $totalRegistros, $dataList, $panelPaginadorTop, $panelPaginadorBottom, $pagerTop, $pagerBottom) {
    $pageSize = $dataList->PageSize;
    $pageCount = $dataList->PageCount;
    if ($totalRegistros <= $pageSize) {
      $panelPaginadorTop->Visible = false;
      $panelPaginadorBottom->Visible = false;
    } else {
      $panelPaginadorBottom->Visible = true;
      $pagerBottom->Visible = true;

      //determina si muestra el paginador del top
      $pagerTop->Visible = ($pageSize > 20) ? true : false;
      $panelPaginadorTop->Visible = $pagerTop->Visible;

      //determina el modo en que se muestran las paginas
      if ($pageCount > 20) {
        $pagerTop->Mode = "DropDownList";
        $pagerBottom->Mode = "DropDownList";
      } else {
        $pagerTop->PageButtonCount = 10;
        $pagerBottom->PageButtonCount = 10;
        $pagerTop->Mode = "Numeric";
        $pagerBottom->Mode = "Numeric";
      }

      //obtiene datos del arreglo a mostrar
      $dataList->VirtualItemCount = $totalRegistros;
      $offset = $dataList->CurrentPageIndex * $pageSize;
      $limit = $pageSize;
      if ($offset + $limit > $dataList->VirtualItemCount) {
        $limit = $dataList->VirtualItemCount - $offset;
      }
      $arr = array_slice($arr, $offset, $limit);
    }
    return $arr;
  }

  public static function encriptarUrl($arr) {
    return base64_encode(json_encode($arr));
  }

  public static function desencriptarUrl($argumento, $key = null) {
    $arr = json_decode(base64_decode($argumento));
    if (is_null($key))
      return $arr;
    try {
      return $arr->$key;
    } catch (Exception $e) {
      return null;
    }
  }

  /**
   * Retorna oEmpresa activa
   * @param type $oUsuarioWf
   * @return type oEmpresa
   */
  public static function obtenerEmpresaActiva($oUsuarioWf) {
    $arrEmpresa = $oUsuarioWf->getEmpresas();
    $empresa = array();
    foreach ($arrEmpresa as $value) {
      if($value["Activo"] == "1"){
        return $value;
      }
      $empresa = $value;
    }
    // si tiene sola una empresa y esta iniciando sesion se activa y se retorna
    if(count($arrEmpresa) == 1){
      $empresa["Activo"] = "1";
      return $empresa;
    }
    return null;
  }

  /**
   * convierte array a utf-8
   * @param <type> $input
   * @return <type>
   */
  public static function utf8_array_encode($input) {
    $return = array();
    foreach ($input as $key => $val) {
      if( is_array($val) ) {
        $return[$key] = self::utf8_array_encode($val);
      } else {
        $return[$key] = utf8_encode($val);
      }
    }
    return $return;
  }

  /**
   * convierte array a utf-8
   * @param <type> $input
   * @return <type>
   */
  public static function utf8_array_decode($input) {
    $return = array();
    foreach ($input as $key => $val) {
      if( is_array($val) ) {
        $return[$key] = self::utf8_array_decode($val);
      } else {
        $return[$key] = utf8_decode($val);
      }
    }
    return $return;
  }


  /**
   * valida si es un email valido
   * @param <type> $texto
   * @return <type>
   * @author VSR, 09/12/2011
   */
  public static function esEmail($texto) {
    $patron = "/^[^0-9][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[@][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[.][a-zA-Z]{2,4}$/";
    if (preg_match($patron,$texto)) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * elimina un numero X de caracteres al final del texto
   * @param <type> $texto
   * @param <type> $totalCaracteresEliminar
   * @return <type> 
   * @author VSR, 09/12/2011
   */
  public static function eliminaUltimosCaracteresTexto($texto, $totalCaracteresEliminar = 1) {
    //calcula largo de texto
    $largoTexto = strlen($texto);

    if ($largoTexto == 0) {
      $texto = "";
    } else {
      //elimina caracteres
      $texto = substr($texto, 0, $largoTexto - $totalCaracteresEliminar);
    }
    return $texto;
  }

  /**
   * obtiene el nombre del estado del paso
   * @param <type> $idPasoEstado 
   * @author VSR, 09/12/2011
   */
  public static function obtenerNombrePasoEstado($idPasoEstado) {
    $nombre = "";
    switch ($idPasoEstado) {
      case WfPasoEstado::ESTADO_APROBADO:
        $nombre = WfPasoEstado::NOMBRE_ESTADO_APROBADO;
        break;
      case WfPasoEstado::ESTADO_CANCELADO:
        $nombre = WfPasoEstado::NOMBRE_ESTADO_CANCELADO;
        break;
      case WfPasoEstado::ESTADO_DEVUELTO:
        $nombre = WfPasoEstado::NOMBRE_ESTADO_DEVUELTO;
        break;
      case WfPasoEstado::ESTADO_PENDIENTE:
        $nombre = WfPasoEstado::NOMBRE_ESTADO_PENDIENTE;
        break;
      case WfPasoEstado::ESTADO_RECHAZADO:
        $nombre = WfPasoEstado::NOMBRE_ESTADO_RECHAZADO;
        break;
      default:
        $nombre = "";
        break;
    }
    return $nombre;
  }

  /**
   * convierte un objeto stdClass en Array
   * @param <type> $object
   * @return <type>
   * @link http://www.phpro.org/examples/Convert-Object-To-Array-With-PHP.html
   */
  public static function objectToArray( $object ) {
    if( !is_object( $object ) && !is_array( $object ) ) {
      return $object;
    }
    if( is_object( $object ) )  {
      $object = get_object_vars( $object );
    }
    return array_map("self::objectToArray", $object );
  }

  /**
   * verifica si tiene acceso al permiso solicitado
   * @param <type> $strPasosJSON
   * @param <type> $idPermiso
   * @author VSR, 11/12/2011
   */
  public static function verificarPermisosPasos($arr, $idPaso, $idPermiso){
    $tienePermiso = false;
    try {
      //obtiene los permisos del paso
      $arrPermisos = $arr[WfFlujo::ARRAY_PASO_PERMISOS];
      $arrPermisos = Utilidades::arrayRowFilter($arrPermisos, "IdPaso == '".$idPaso."' && IdPermiso == '".$idPermiso."'");
      $totalRegistros = count($arrPermisos);
      if ($totalRegistros > 0 ) { $tienePermiso = true; }
    } catch (Exception $e) {
      $tienePermiso = false;
    }
    return $tienePermiso;
  }

  /**
   * obtiene orden del paso consultado
   * @param <type> $arr
   * @param <type> $idPaso
   * @return string
   * @author VSR, 02/05/2012
   */
  public static function obtenerOrdenPaso($arr, $idPaso){
    $orden = "";
    try {
      //obtiene los permisos del paso
      $arrPasos = $arr[WfFlujo::ARRAY_PASO_LISTADO];
      $arrPasos = Utilidades::arrayRowFilter($arrPasos, "IdPaso == '".$idPaso."'");
      $totalRegistros = count($arrPasos);
      if ($totalRegistros > 0 ) { $orden = $arrPasos[0]["OrdenPaso"]; }
    } catch (Exception $e) {
      $orden = "";
    }
    return $orden;
  }

  /**
   * obtiene total de pasos
   * @param <type> $arr
   * @param <type> $idPaso
   * @return string
   * @author VSR, 02/05/2012
   */
  public static function obtenerTotalPasos($arr){
    $cantidad = 0;
    try {
      //obtiene los permisos del paso
      $arrPasos = $arr[WfFlujo::ARRAY_PASO_LISTADO];
      $cantidad = count($arrPasos);
    } catch (Exception $e) {
      $cantidad = 0;
    }
    return $cantidad;
  }

  /**
   * verifica si tiene acceso al permiso solicitado
   * @param <type> $arr
   * @param <type> $idPermiso
   * @return boolean
   * @author VSR, 06/02/2012
   */
  public static function verificarPermisosEncargado($arr, $idPermiso){
    $tienePermiso = false;
    try {
      //obtiene los permisos del paso
      $arrPermisos = $arr[WfFlujo::ARRAY_PASO_ENCARGADOS_PERMISOS];
      $arrPermisos = Utilidades::arrayRowFilter($arrPermisos, "IdPermiso == '".$idPermiso."'");
      $totalRegistros = count($arrPermisos);
      if ($totalRegistros > 0 ) { $tienePermiso = true; }
    } catch (Exception $e) {
      $tienePermiso = false;
    }
    return $tienePermiso;
  }

  /**
   * verifica si el usuario es aprobador en paso actual
   * @param <type> $strPasosJSON
   * @param <type> $idPermiso
   * @author VSR, 11/12/2011
   */
  public static function esAprobadorPasoActual($arr, $idPaso, $idUsuario){
    $esAprobador = false;
    try {
      //obtiene los permisos del paso
      $arrAprobadores = $arr[WfFlujo::ARRAY_PASO_APROBADORES];
      $arrAprobadores = Utilidades::arrayRowFilter($arrAprobadores, "IdPaso == '".$idPaso."' && IdUsuario == '".$idUsuario."'");
      $totalRegistros = count($arrAprobadores);
      if ($totalRegistros > 0 ) { $esAprobador = true; }
    } catch (Exception $e) {
      $esAprobador = false;
    }
    return $esAprobador;
  }


  /**
   * arma el queryString segun la pagina solicitada
   * @param <type> $json
   * @return string
   */
  public static function obtenerQueryStringRedirect($json){
    $queryString="";
    try {
      $arr = json_decode($json);
      $pagina = $arr->pg;

      switch ($pagina) {
        case "":
          $queryString = "";
          break;
        default:
          $idWorkflow = $arr->wf;
          $idEmpresa = $arr->em;
          $idFlujo = $arr->fl;
          $idPaso = $arr->ps;
          $idCache = $arr->ca;
          $idHistorial = $arr->hs;
          $replicarDatos = $arr->rd;
          $cargarFiltrosSesion = $arr->cfs;
          $paginaFiltro = $arr->pf;
          $queryString = Utilidades::obtenerQueryStringFlujo(Utilidades::QUERYSTRING_FLUJO_NORMAL, "", $idFlujo, $idWorkflow, $idEmpresa, $idPaso, $idCache, $idHistorial,$replicarDatos,$cargarFiltrosSesion,$paginaFiltro);
          $queryString = "page=".$pagina."&a=".$queryString;
          self::seleccionarEmpresaActiva($idEmpresa);
          break;
      }
     
    } catch (Exception $e) {
      $queryString="";
    }
    return $queryString;
  }

  /**
   * cambia los numeros por letras
   * @param <type> $texto
   * @param <type> $opcion 
   * @author VSR, 23/12/2011
   */
  public static function encriptarNumero($texto, $opcion) {
    if($opcion == self::NUMERO_ENCRIPTAR) {
      $texto = str_replace("0", "|K|", $texto);
      $texto = str_replace("1", "|R|", $texto);
      $texto = str_replace("2", "|W|", $texto);
      $texto = str_replace("3", "|A|", $texto);
      $texto = str_replace("4", "|T|", $texto);
      $texto = str_replace("5", "|Q|", $texto);
      $texto = str_replace("6", "|J|", $texto);
      $texto = str_replace("7", "|C|", $texto);
      $texto = str_replace("8", "|U|", $texto);
      $texto = str_replace("9", "|B|", $texto);
    } else {
      $texto = str_replace("|K|", "0",$texto);
      $texto = str_replace("|R|", "1",$texto);
      $texto = str_replace("|W|", "2",$texto);
      $texto = str_replace("|A|", "3",$texto);
      $texto = str_replace("|T|", "4",$texto);
      $texto = str_replace("|Q|", "5",$texto);
      $texto = str_replace("|J|", "6",$texto);
      $texto = str_replace("|C|", "7",$texto);
      $texto = str_replace("|U|", "8",$texto);
      $texto = str_replace("|B|", "9",$texto);
    }
    return $texto;
  }

  /**
   * graba la imagen del fileUpload
   * @param <type> $objFileUpload
   * @param <type> $idRegistro
   * @param <type> $entidad
   * @author VSR, 19/12/2011
   */
  public static function grabarArchivoFileUpload($objFileUpload, $idRegistro, $entidad) {
    try {
      $oUsuario = self::obtenerSessionPorNombre(Usuario::NOMBRE_ENTIDAD);

      if($objFileUpload->HasFile) {
        $nombreArchivo = $objFileUpload->FileName;
        //quita caracteres especiales
        $nombreArchivo = Archivo::reemplazarCaracteresEspeciales($nombreArchivo);
        $contentType = $objFileUpload->FileType;
        $tamano = $objFileUpload->FileSize;
        $extension = Archivo::obtenerExtensionArchivo($nombreArchivo);
        $idUsuario = $oUsuario->getId();
        $idArchivo = Archivo::grabaEnBaseDatos($idUsuario, $nombreArchivo, $extension, $contentType);

        $status = Archivo::asociarArchivoConRegistro($idArchivo, $idRegistro, $entidad, $tamano);
        $directorioArchivoDestino = Archivo::RUTA_REPOSITORIO."/".$entidad."/reg".$idRegistro."/".$idArchivo;
        if(!Archivo::existeDirectorio($directorioArchivoDestino)) {
          Archivo::crearDirectorio($directorioArchivoDestino);
        }
        //copia el archivo al directorio destino
        $rutaImagen = $directorioArchivoDestino."/".$nombreArchivo;
        $objFileUpload->saveAs($rutaImagen);

        //redimensiona imagen para entidades especiales
        switch ($entidad) {
          case WfEmpresa::NOMBRE_ENTIDAD_LOGO:
            self::redimensionarImagen($rutaImagen,"0","80");
            break;
          case UsuarioWf::NOMBRE_ENTIDAD_FIRMA:
            self::redimensionarImagen($rutaImagen,"0","100");
            break;
          default:
            break;
        }
      }
    } catch (Exception $e) {
      throw new Exception($e->getMessage());
    }
  }

  /**
   * compara 2 array y determina si son iguales
   * @param <type> $arr1
   * @param <type> $arr2
   * @param <type> $opcion
   * @return boolean
   * @author VSR, 06/01/2012
   */
  public static function compararArray($arr1, $arr2, $opcion = self::COMPARAR_ARRAY_EXACTO) {
    $esIgual = true;
    try {
      switch ($opcion) {
        case self::COMPARAR_ARRAY_EXACTO:
          $result = array_diff_assoc($arr1, $arr2);
          break;
        case self::COMPARAR_ARRAY_CONTENIDO:
          $result = self::array_diff_xor($arr1, $arr2);
          break;
        default:
          $result = array_diff_assoc($arr1, $arr2);
          break;
      }

      if(count($result) > 0 ) {
        $esIgual = false;
      }
    } catch (Exception $e) {
      $esIgual = true;
    }
    return $esIgual;
  }

  /**
   * verifica las diferencias en ambos array
   * @param <type> $array_a
   * @param <type> $array_b
   * @return <type>
   * @link http://php.net/manual/es/function.array-diff.php
   */
  public static function array_diff_xor($array_a, $array_b) {
    $union_array = array_merge($array_a, $array_b);
    $intersect_array = array_intersect($array_a, $array_b);
    return array_diff($union_array, $intersect_array);
  }

  /**
   * encode o decodea un array
   * @param <type> $arr
   * @param <type> $opcion
   * @return <type>
   * @author VSR, 06/01/2012
   */
  public static function urlencodeArray($arr, $opcion) {
    $newArr = null;

    try {
      $totalRegistros = count($arr);
      for ($i = 0; $i <= $totalRegistros -1; $i++){
        $valor = $arr[$i];
        $valor = ($opcion == self::ARRAY_URL_DECODE) ? urldecode($valor) : urlencode($valor);
        $arr[$i] = $valor;
      }
      $newArr = $arr;
    } catch (Exception $e) {
      $newArr = $arr;
    }
    return $newArr;
  }

  /**
   * envia email por el orden del paso
   * @param <type> $arrPasos
   * @param <type> $ordenPaso 
   * @author VSR, 25/01/2012
   */
  public static function enviarEmailPorOrdenPaso($nombrePagina, $arr, $arrPasos, $ordenPaso, $idWorkflow, $idEmpresa, $nombreFlujo, $idEstado, $idFlujo, $objService, $objApplication, $idCache, $idHistorial) {
    try {
      $oWorkflow = new WfWorkflow();
      $oWorkflow->obtenerPorId($idWorkflow);
      $listadoAprobadores = "";
      //obtiene idPaso al que se debe dirigir
      $arrPasoProximaAccion = Utilidades::arrayRowFilter($arrPasos, "OrdenPaso == '".$ordenPaso."'");
      $idPaso = $arrPasoProximaAccion[0]["IdPaso"];
      $totalPasos = count($arrPasos);

      //verifica si tiene permiso para enviar mail
      $puedeEnviarEmail = Utilidades::verificarPermisosPasos($arr, $idPaso, WfPermiso::NOTIFICAR_POR_EMAIL);
      $puedeEnviarEmailEncargado = Utilidades::verificarPermisosEncargado($arr, WfPermiso::NOTIFICAR_POR_EMAIL);

      //si tiene permiso busca los aprobadores
      if ($puedeEnviarEmail || $puedeEnviarEmailEncargado) {
          //obtiene plazo de aprobacion
          $strValorPlazo = $arrPasoProximaAccion[0]["ValorPlazo"];
          $strUnidadMedidaValor = $arrPasoProximaAccion[0]["UnidadMedidaTexto"];
          $strValorPlazo = $strValorPlazo . " " . $strUnidadMedidaValor;

          //envia mail a aprobadores
          if($puedeEnviarEmail) {
            //obtiene los aprobadores del paso
            $arrAprobadores = $arr[WfFlujo::ARRAY_PASO_APROBADORES];
            $arrAprobadores = Utilidades::arrayRowFilter($arrAprobadores, "IdPaso == '" . $idPaso . "'");
            $totalRegistros = count($arrAprobadores);
            for ($i = 0; $i <= $totalRegistros - 1; $i++) {
              $row = $arrAprobadores[$i];
              $email = $row["Email"];
              if (Utilidades::esEmail($email)) {
                $listadoAprobadores .= $email . ";";
              }
            }
          }

          //envia mail a encargados
          if($puedeEnviarEmailEncargado) {
            //obtiene los encargados
            $arrEncargados = $arr[WfFlujo::ARRAY_PASO_ENCARGADOS];
            $totalRegistros = count($arrEncargados);
            for ($i = 0; $i <= $totalRegistros - 1; $i++) {
              $row = $arrEncargados[$i];
              $email = $row["Email"];
              if (Utilidades::esEmail($email)) {
                $listadoAprobadores .= $email . ";";
              }
            }
          }

          //si hay aprobadores por notificar, entonces envia el email
          if (!Utilidades::isNullOrEmpty($listadoAprobadores)) {
            $listadoAprobadores = Utilidades::eliminaUltimosCaracteresTexto($listadoAprobadores);

            //obtiene el template para dibujar el menu
            $pathBase = Utilidades::obtenerDirectorioBaseAplicacion();
            $template = Utilidades::obtenerContenidoPlantillaHTML($pathBase."template".DIRECTORY_SEPARATOR."AvisoEmailPasoFlujo.html", true);

            //construye URL
            $oEmpresa = new WfEmpresa;
            $oEmpresa->obtenerPorId($idEmpresa);
            $queryString = Utilidades::obtenerQueryStringFlujo(Utilidades::QUERYSTRING_FLUJO_MINIMO, $nombrePagina, $idFlujo, $idWorkflow, $idEmpresa, $idPaso, $idCache, $idHistorial,"0","0","");

            //construye la url segun la empresa del usuario
            $urlPagina = $objService->constructUrl($nombrePagina);
            $pos = strpos($urlPagina, "/Web");
            $carpetaDirectorioVirtual = substr($urlPagina, 0,$pos);
            $strUrl = Utilidades::obtenerDirectorioVirtual().$carpetaDirectorioVirtual."/".$oEmpresa->getUrl()."/".$queryString;
            $strNombrePasoEstado = Utilidades::obtenerNombrePasoEstado($idEstado);
            $strOrdenPaso = $ordenPaso." de ".$totalPasos;
            $strNombreWorkflow = $oWorkflow->getNombre();

            //reemplaza marcas en el template
            $template = str_replace("{#NOMBRE_PASO_ESTADO}", strtoupper($strNombrePasoEstado), $template);
            $template = str_replace("{#NOMBRE_WORKFLOW}", strtoupper($strNombreWorkflow), $template);
            $template = str_replace("{#NOMBRE_FLUJO}", strtoupper($nombreFlujo), $template);
            $template = str_replace("{#PLAZO}", $strValorPlazo, $template);
            $template = str_replace("{#PASO}", $strOrdenPaso, $template);
            $template = str_replace("{#URL}", htmlentities($strUrl), $template);

            if (Utilidades::modoDebug()) {
              $listadoMailPara = Utilidades::emailPruebas();
              $listadoMailCCO = "";
            } else {
              $listadoMailPara = $listadoAprobadores;
              $listadoMailCCO = Utilidades::emailAdministrador();
            }

            $msg = Mail::enviar(
                    Utilidades::emailHost($objApplication),
                    Utilidades::emailUsername($objApplication),
                    Utilidades::emailPassword($objApplication),
                    Utilidades::emailNombreEmisor($objApplication),
                    "Aviso de flujo para aprobar",
                    $template,
                    true,
                    $listadoMailPara,
                    "",
                    $listadoMailCCO, "");
          }
      }
    } catch (Exception $e) {
      //no hace nada
    }
  }

  /**
   * selecciona la empresa activa
   * @param <type> $idEmpresa
   */
  public static function seleccionarEmpresaActiva($idEmpresa) {
    try {
      $oUsuarioWf = new UsuarioWf();
      $oUsuarioWf = self::obtenerSessionPorNombre(Usuario::NOMBRE_ENTIDAD);
      $arrEmpresa = $oUsuarioWf->getEmpresas();
      $arrNuevaEmpresa = array();
      foreach ($arrEmpresa as $value) {
        if ($value["Id"] == $idEmpresa) {
          $value["Activo"] = "1";
        }else{
          $value["Activo"] = "0";
        }
        $arrNuevaEmpresa[] = $value;
      }
      $oUsuarioWf->setEmpresas($arrNuevaEmpresa);
      self::grabarSessionPorNombre(Usuario::NOMBRE_ENTIDAD, $oUsuarioWf);

    } catch (Exception $e) {
      //no hace nada
    }
  }

  /**
   * envia email a los encargados
   * @param <type> $arr
   * @param <type> $arrPasos
   * @param <type> $ordenPaso
   * @param <type> $idWorkflow
   * @param <type> $idEmpresa
   * @param <type> $nombreFlujo
   * @param <type> $idEstado
   * @param <type> $idFlujo
   * @param <type> $objService
   * @param <type> $objApplication
   * @param <type> $idCache
   * @param <type> $nombreAprobador
   * @param <type> $observacion
   * @param <type> $fechaActual
   * @author VSR, 01/02/2012
   */
  public static function enviarEmailEncargados($nombrePagina, $arr, $arrPasos, $ordenPaso, $idWorkflow, $idEmpresa, $nombreFlujo, $idEstado, $idFlujo,
                                               $objService, $objApplication, $idCache, $nombreAprobador, $observacion, $fechaActual, $idHistorial) {
    try {
      $oWorkflow = new WfWorkflow();
      $oWorkflow->obtenerPorId($idWorkflow);
      $listadoEncargados = "";

      //obtiene datos del creador del flujo
      $arrCreadorFlujo = WfFlujo::obtenerDatosCreadorFlujo($idFlujo);
      if (!Utilidades::isNullOrEmpty($arrCreadorFlujo)) {
        $row = $arrCreadorFlujo[0];
        $email = $row["Email"];
        if (Utilidades::esEmail($email)) {
          $listadoEncargados .= $email . ";";
        }
      }

      //obtiene idPaso al que se debe dirigir
      $arrPasoProximaAccion = Utilidades::arrayRowFilter($arrPasos, "OrdenPaso == '".$ordenPaso."'");
      $idPaso = $arrPasoProximaAccion[0]["IdPaso"];

      //obtiene encargados
      $arrEncargados = $arr[WfFlujo::ARRAY_PASO_ENCARGADOS];
      $totalPasos = count($arrPasos);

      //obtiene los aprobadores del paso
      $totalRegistros = count($arrEncargados);
      for ($i = 0; $i <= $totalRegistros - 1; $i++) {
        $row = $arrEncargados[$i];
        $email = $row["Email"];
        if (Utilidades::esEmail($email)) {
          $listadoEncargados .= $email . ";";
        }
      }

      //si hay aprobadores por notificar, entonces envia el email
      if (!Utilidades::isNullOrEmpty($listadoEncargados)) {
        $listadoEncargados = Utilidades::eliminaUltimosCaracteresTexto($listadoEncargados);

        //obtiene el template para dibujar el menu
        $pathBase = Utilidades::obtenerDirectorioBaseAplicacion();
        $template = Utilidades::obtenerContenidoPlantillaHTML($pathBase."template".DIRECTORY_SEPARATOR."AvisoEmailEncargados.html", true);

        //construye URL
        $oEmpresa = new WfEmpresa;
        $oEmpresa->obtenerPorId($idEmpresa);
        $queryString = Utilidades::obtenerQueryStringFlujo(Utilidades::QUERYSTRING_FLUJO_MINIMO, $nombrePagina, $idFlujo, $idWorkflow, $idEmpresa, $idPaso, $idCache, $idHistorial,"0","0","");

        //construye la url segun la empresa del usuario
        $urlPagina = $objService->constructUrl($nombrePagina);
        $pos = strpos($urlPagina, "/Web");
        $carpetaDirectorioVirtual = substr($urlPagina, 0,$pos);
        $strUrl = Utilidades::obtenerDirectorioVirtual().$carpetaDirectorioVirtual."/".$oEmpresa->getUrl()."/".$queryString;
        $strNombrePasoEstado = Utilidades::obtenerNombrePasoEstado($idEstado);
        $strOrdenPaso = $ordenPaso." de ".$totalPasos;
        $strNombreWorkflow = $oWorkflow->getNombre();

        //reemplaza marcas en el template
        $template = str_replace("{#NOMBRE_PASO_ESTADO}", strtoupper($strNombrePasoEstado), $template);
        $template = str_replace("{#NOMBRE_WORKFLOW}", strtoupper($strNombreWorkflow), $template);
        $template = str_replace("{#NOMBRE_FLUJO}", strtoupper($nombreFlujo), $template);
        $template = str_replace("{#NOMBRE_APROBADOR}", $nombreAprobador, $template);
        $template = str_replace("{#FECHA}", $fechaActual, $template);
        $template = str_replace("{#OBSERVACION}", $observacion, $template);
        $template = str_replace("{#URL}", htmlentities($strUrl), $template);

        if (Utilidades::modoDebug()) {
          $listadoMailPara = Utilidades::emailPruebas();
          $listadoMailCCO = "";
        } else {
          $listadoMailPara = $listadoEncargados;
          $listadoMailCCO = Utilidades::emailAdministrador();
        }

        $msg = Mail::enviar(
                Utilidades::emailHost($objApplication),
                Utilidades::emailUsername($objApplication),
                Utilidades::emailPassword($objApplication),
                Utilidades::emailNombreEmisor($objApplication),
                "Aviso de flujo rechazado o cancelado",
                $template,
                true,
                $listadoMailPara,
                "",
                $listadoMailCCO, "");
      }
    } catch (Exception $e) {
      //no hace nada
    }
  }

  /**
   * construye url json para el flujo
   * @param <type> $idFlujo
   * @param <type> $idWorkflow
   * @param <type> $idEmpresa
   * @param <type> $idPaso
   * @param <type> $idCache
   * @param <type> $idHistorial
   * @return <type>
   * @author VSR, 04/04/2012
   */
  public static function obtenerQueryStringFlujo($opcion, $pagina, $idFlujo, $idWorkflow, $idEmpresa, $idPaso, $idCache, $idHistorial, $replicarDatos,
                                                 $cargarFiltrosSesion, $paginaFiltro){
    $queryString = "";

    if ($opcion == self::QUERYSTRING_FLUJO_NORMAL){
      $queryString .= "{";
      $queryString .= " \"IdFlujo\":\"".$idFlujo."\"";
      $queryString .= ",\"IdWorkflow\":\"".$idWorkflow."\"";
      $queryString .= ",\"IdEmpresa\":\"".$idEmpresa."\"";
      $queryString .= ",\"IdPaso\":\"".$idPaso."\"";
      $queryString .= ",\"IdCache\":\"".$idCache."\"";
      $queryString .= ",\"IdHistorial\":\"".$idHistorial."\"";
      $queryString .= ",\"ReplicarDatos\":\"".$replicarDatos."\"";
      $queryString .= ",\"CargarFiltrosSesion\":\"".$cargarFiltrosSesion."\"";
      $queryString .= ",\"PaginaFiltro\":\"".$paginaFiltro."\"";
      $queryString .= "}";
      $queryString = Criptografia::encriptarURL($queryString);
    } else {
      $queryString .= "{";
      $queryString .= " \"pg\":\"".$pagina."\"";
      $queryString .= ",\"fl\":\"".$idFlujo."\"";
      $queryString .= ",\"wf\":\"".$idWorkflow."\"";
      $queryString .= ",\"em\":\"".$idEmpresa."\"";
      $queryString .= ",\"ps\":\"".$idPaso."\"";
      $queryString .= ",\"ca\":\"".$idCache."\"";
      $queryString .= ",\"hs\":\"".$idHistorial."\"";
      $queryString .= ",\"rd\":\"".$replicarDatos."\"";
      $queryString .= ",\"cfs\":\"".$cargarFiltrosSesion."\"";
      $queryString .= ",\"pf\":\"".$paginaFiltro."\"";
      $queryString .= "}";
      $queryString = Utilidades::encriptarNumero($queryString, Utilidades::NUMERO_ENCRIPTAR);
    }
    
    return $queryString;
  }

  /**
   * replica el archivo
   * @param <type> $idArchivo
   * @param <type> $idRegistro
   * @param <type> $idRegistroPadre
   * @param <type> $entidad
   * @author VSR, 11/04/2012
   */
  public static function replicarArchivo($idArchivoReplica, $idRegistro, $idRegistroPadre, $entidad) {
    try {
      $oUsuario = self::obtenerSessionPorNombre(Usuario::NOMBRE_ENTIDAD);
      $idUsuario = $oUsuario->getId();
      $arr = Archivo::replicarDatos($idUsuario, $idArchivoReplica, $idRegistro);
      $pathBase = Utilidades::obtenerDirectorioBaseAplicacion();
      $templatePath = $pathBase.Archivo::RUTA_REPOSITORIO.DIRECTORY_SEPARATOR."{entidad}".DIRECTORY_SEPARATOR."reg{idRegistro}".DIRECTORY_SEPARATOR."{idArchivo}".DIRECTORY_SEPARATOR."{nombreArchivo}";

      if(!is_null($arr)) {
        $totalRegistros = count($arr[0]);
        if($totalRegistros > 0) {
          $row = $arr[0];
          $idArchivo = $row["IdArchivo"];
          $nombreArchivo = $row["NombreArchivo"];
        }
      }

      //construye path origen
      $rutaOrigen = $templatePath;
      $rutaOrigen = str_replace("{entidad}", $entidad, $rutaOrigen);
      $rutaOrigen = str_replace("{idRegistro}", $idRegistroPadre, $rutaOrigen);
      $rutaOrigen = str_replace("{idArchivo}", $idArchivoReplica, $rutaOrigen);
      $rutaOrigen = str_replace("{nombreArchivo}", $nombreArchivo, $rutaOrigen);

      //construye path destino
      $directorioArchivoDestino = Archivo::RUTA_REPOSITORIO."/".$entidad."/reg".$idRegistro."/".$idArchivo;
      if(!Archivo::existeDirectorio($directorioArchivoDestino)) {
        Archivo::crearDirectorio($directorioArchivoDestino);
      }
      $rutaDestino = $templatePath;
      $rutaDestino = str_replace("{entidad}", $entidad, $rutaDestino);
      $rutaDestino = str_replace("{idRegistro}", $idRegistro, $rutaDestino);
      $rutaDestino = str_replace("{idArchivo}", $idArchivo, $rutaDestino);
      $rutaDestino = str_replace("{nombreArchivo}", $nombreArchivo, $rutaDestino);

      if (!copy($rutaOrigen, $rutaDestino)) {
        throw new Exception("No se pudo copiar el archivo $rutaOrigen");
      }
    } catch (Exception $e) {
      throw new Exception($e->getMessage());
    }
  }

  /**
   * construye un nombre unico para un archivo a partir de la fecha actual
   * @author VSR, 15/04/2012
   */
  public static function obtenerNombreUnicoArchivo($sufijo = "") {
    date_default_timezone_set(self::ZONA_HORARIA);
    $nombre = date("Y_m_d_H_i_s");
    if(!self::isNullOrEmpty($sufijo)){
      $sufijo = preg_replace('/[^aA-zZ0-9\_\-]/', '', $sufijo);
      $nombre .= "_".$sufijo;
    }
    return $nombre;
  }

  /**
   * formatea un array para asignar los datos a una hoja excel
   * @param <type> $arr 
   * @author VSR, 15/04/2012
   */
  public static function obtenerArrayHojaExcel($arr) {
    $data = null;
    try {
      //asigna el nombre de las columnas
      $arrColumnas = array_keys($arr[0]);
      $data[] = $arrColumnas;

      //obtiene las filas con los datos
      $totalRegistros = count($arr);
      for($i = 0; $i <= $totalRegistros - 1; $i++) {
        $row = $arr[$i];
        $data[] = $row;
      }
      return $data;
    } catch (Exception $e) {
      throw new Exception($e->getMessage());
    }
  }

  /**
   * obtiene id de la empresa activa
   * @return <type> 
   * @author VSR, 24/04/2012
   */
  public static function obtenerIdEmpresaActiva() {
    try {
      $oUsuarioWf = new UsuarioWf();
      $oUsuarioWf = Utilidades::obtenerSessionPorNombre(Usuario::NOMBRE_ENTIDAD);
      $oEmpresa = Utilidades::obtenerEmpresaActiva($oUsuarioWf);
      $idEmpresa = $oEmpresa["Id"];
      return $idEmpresa;
    } catch (Exception $e) {
      $idEmpresa = "-1";
    }
    return $idEmpresa;
  }

  /**
   * redimensiona el tamaño de una imagen
   * @param <type> $entidad
   * @param <type> $rutaImagen
   * @param <type> $width
   * @param <type> $height
   * @author VSR, 24/12/2012
   */
  public static function redimensionarImagen($rutaImagen, $width, $height) {
    try {
      $pathBase = Utilidades::obtenerDirectorioBaseAplicacion();
      $rutaImagen2 = $pathBase.$rutaImagen;

      $obj = new ResizeImage();
      $obj->max_width($width);
      $obj->max_height($height);
      $obj->image_path($rutaImagen);
      $obj->image_resize();
    } catch (Exception $e) {
      //no hace nada
    }
  }

  /**
   * obtiene los aprobadores por paso
   * @param <type> $listadoAprobadores
   * @param <type> $nombreTooltips
   * @param <type> $tieneTooltips
   * @param <type> $contenidoTooltips
   * @return <type>
   */
  public static function formatearAprobadoresPorPaso($listadoAprobadores, $nombreTooltips, &$tieneTooltips, &$contenidoTooltips, $themeBaseUrl) {
    try {
      $text = "";
      $listadoAprobadores = self::eliminaUltimosCaracteresTexto($listadoAprobadores, 2);
      $arrAprobadores = explode("; ", $listadoAprobadores);
      $totalAprobadores = count($arrAprobadores);

      if ($totalAprobadores > 0) {
        if ($totalAprobadores == 1){
          $text = $listadoAprobadores;
          $tieneTooltips = false;
          $contenidoTooltips = "";
        } else {
          $listadoAprobadores = implode("<br/>", $arrAprobadores);
          $text = "<span id=\"".$nombreTooltips."\"><img src=\"".$themeBaseUrl."/img/lupa.gif\" style=\"vertical-align:middle\" />M&aacute;s de uno...</span>";
          $tieneTooltips = true;
          $contenidoTooltips = "<span style=\"font-size:13px;\"><b>Aprobadores</b></span><br/>".$listadoAprobadores;
        }
      }
      return $text;
    } catch (Exception $e) {
      return "";
    }
  }

  public static function dateToDDMMYYYY($date) {
    if (!empty($date)) {
      $var = explode('/', str_replace('-', '/', $date));
      return "$var[2]/$var[1]/$var[0]";
    }
  }
  
  public static function dateToYYYYMMDD($date) {
    if (!empty($date)) {
      $var = explode('/', str_replace('-', '/', $date));
      return "$var[2]-$var[1]-$var[0]";
    }
  }

  /**
   * reasigna el indice a un array
   * @param <type> $arr
   * @author VSR, 07/05/2012
   */
  public static function reasignarIndiceArray($arr){
    try {
      $newArray= array();
      foreach($arr as $item){
        $newArray[] = $item;
      }
    } catch (Exception $e) {
      $newArray = $arr;
    }
    return $newArray;
  }

  /**
   * elimina una fila del array en sesion
   * @param <type> $indice
   * @return <type>
   * @author VSR, 10/05/2012
   */
  public static function eliminarFilaSesion($indice, $nombreSesion) {
    $retorno = "";
    try {
      $arr = self::obtenerSessionPorNombre($nombreSesion);
      if (is_null($arr)) {
        $totalRegistros = 0;
      } else {
        $totalRegistros = count($arr);
      }

      //si hay registros entonces los elimina
      if($totalRegistros > 0) {
        unset($arr[$indice]);
        //reasigan los indices del array
        $arr = self::reasignarIndiceArray($arr);
        self::grabarSessionPorNombre($nombreSesion, $arr);
      }
    } catch (Exception $e) {
      $retorno = Sistema::CODIGO_SQL_ERROR;
    }
    return $retorno;
  }

  /**
   * separa el rut del digito verificador
   * @param <type> $rut
   * @param string $dv
   * @author VSR, 14/05/2012
   */
  public static function separarRut(&$rut,&$dv) {
    try {
      if(self::isNullOrEmpty($rut)){
        $rut = "";
        $dv = "";
      } else {
        $rut = str_replace(".", "", $rut);
        $rut = str_replace(" ", "", $rut);
        $rut = str_replace("-", "", $rut);
        $largo = strlen($rut);
        $dv = substr($rut, $largo-1, $largo);
        $rut = substr($rut, 0, $largo-1);
      }
    } catch (Exception $e) {
      $dv = "";
    }
  }

  /**
   * obtiene la imagen del color del semaforo
   * @param <type> $diferenciaEnMinutos
   * @param <type> $valorPlazo
   * @param <type> $unidadMedidaPlazo
   * @param <type> $valorSemaforoAmarillo
   * @param <type> $unidadMedidaSemaforoAmarillo
   * @return string
   * @author VSR, 25/05/2012
   */
  public static function obtenerImagenColorSemaforo($diferenciaEnMinutos, $valorPlazo, $unidadMedidaPlazo, $valorSemaforoAmarillo, $unidadMedidaSemaforoAmarillo, &$diasAtraso, $textoPrefijo = ""){
    try {
      $minutosPlazo = self::transformarPlazoMinutos($valorPlazo, $unidadMedidaPlazo);
      $minutosSemaforoAmarillo = self::transformarPlazoMinutos($valorSemaforoAmarillo, $unidadMedidaSemaforoAmarillo);

      //si el tiempo que lleva es menor o igual que el tiempo que falta para al semaforo en amarillo, entonces esta ok
      if($diferenciaEnMinutos <= $minutosSemaforoAmarillo){
        //verde
        $imgColorEstado = "verde.png";
      //si el tiempo que lleva es mayor que del semaforo, pero es menor al tiempo total del plazo, entoces es amarillo
      } else if ($diferenciaEnMinutos > $minutosSemaforoAmarillo && $diferenciaEnMinutos <= $minutosPlazo){
        //amarillo
        $imgColorEstado = "amarillo.png";
      //si el tiempo que mayor que el plazo total, entonces rojo
      } else {
        //rojo
        $imgColorEstado = "rojo.png";
      }
    } catch (Exception $e) {
      $imgColorEstado = "";
    }
    $minutosAtraso = $minutosPlazo - $diferenciaEnMinutos;
    $diasAtraso = self::formatearDiasAtraso($minutosAtraso, $textoPrefijo);
    return $imgColorEstado;
  }

  /**
   * obtiene el color del flujo si esta atrasado
   * @param <type> $diferenciaEnMinutos
   * @param <type> $valorPlazo
   * @param <type> $unidadMedidaPlazo
   * @param <type> $diasAtraso
   * @return string 
   * @author VSR, 28/05/2012
   */
  public static function obtenerColorFlujo($diferenciaEnMinutos, $valorPlazo, $unidadMedidaPlazo, &$diasAtraso, $textoPrefijo = ""){
    try {
      $minutosPlazo = self::transformarPlazoMinutos($valorPlazo, $unidadMedidaPlazo);

      //si el tiempo que lleva es menor o igual que el tiempo que falta para al semaforo en amarillo, entonces esta ok
      if($diferenciaEnMinutos <= $minutosPlazo){
        //verde
        $colorFlujo = WfFlujo::COLOR_VERDE;
      //si el tiempo que mayor que el plazo total, entonces rojo
      } else {
        //rojo
        $colorFlujo = WfFlujo::COLOR_ROJO;
      }
    } catch (Exception $e) {
      $colorFlujo = "";
    }
    $minutosAtraso = $minutosPlazo - $diferenciaEnMinutos;
    $diasAtraso = self::formatearDiasAtraso($minutosAtraso, $textoPrefijo);
    return $colorFlujo;
  }

  /**
   * transforma los plazos en minutos
   * @param <type> $valor
   * @param <type> $unidadMedida
   * @return <type>
   * @author VSR, 25/05/2012
   */
  public static function transformarPlazoMinutos($valor, $unidadMedida) {
    switch ($unidadMedida) {
      case self::UNIDAD_MEDIDA_MINUTO:
          $valor = $valor * 1;
        break;
      case self::UNIDAD_MEDIDA_HORA:
          $valor = $valor * 60;
        break;
      case self::UNIDAD_MEDIDA_DIA:
          $valor = $valor * 1440;
        break;
      default:
        $valor = $valor * 1;
        break;
    }
    return $valor;
  }

  /**
   * formatea el texto de salida de los dias de atraso
   * @param <type> $minutosAtraso
   * @author VSR, 25/05/2012
   */
  public static function formatearDiasAtraso($minutosAtraso, $textoPrefjio = ""){
    $texto = "";
    $unidadTiempo = "";
    try {
      //lo transforma en dias (parte entera)
      $plazoAtraso = abs((int)($minutosAtraso/1440));
      if($plazoAtraso >= 1){
        $unidadTiempo = " ".( ($plazoAtraso == 1) ? "d&iacute;a" : "d&iacute;as");
      } else {
        //lo transforma en horas (parte entera)
        $plazoAtraso = abs((int)($minutosAtraso/60));
        if($plazoAtraso >= 1){
          $unidadTiempo = " ".( ($plazoAtraso == 1) ? "hora" : "horas");
        } else {
          $plazoAtraso = abs($minutosAtraso);
          $unidadTiempo = " ".( ($plazoAtraso == 1) ? "minuto" : "minutos");
        }
      }

      $texto = $plazoAtraso.$unidadTiempo;


      if ($minutosAtraso >= 0) {
        $texto = ($plazoAtraso == 1) ? "queda ".$texto : "quedan ".$texto;
      } else {
        $texto = ($plazoAtraso == 1) ? "atrasado en ".$texto : "atrasado en ".$texto;
        $texto = "<span class=\"cssMensajeError\">".(self::isNullOrEmpty($textoPrefjio) ? "" : $textoPrefjio."&nbsp;" ).$texto."</span>";
      }
    } catch (Exception $e) {
      $texto = "";
    }
    return str_replace(".", ",", $texto);
  }

  /**
   * obtiene la parte del marco a dibujar
   * @param <type> $titulo
   * @param <type> $posicion
   * @param <type> $tipo
   * @param <type> $nombreControlImagenExpandirContraer
   * @return <type>
   * @author VSR, 15/06/2012
   */
  public static function obtenerMarco($posicion, $titulo = "", $tipo = self::MARCO_TIPO_NORMAL, $nombreControlImagenExpandirContraer = "", $classTitulo = self::MARCO_CSS_TITULO) {
    $html = "";
    try {
      //obtiene el template para dibujar el menu
      $pathBase = self::obtenerDirectorioBaseAplicacion();
      $template = self::obtenerContenidoPlantillaHTML($pathBase."template".DIRECTORY_SEPARATOR."Marco.html", true);
      $tagBegin = "<!-- begin-marco-".strtolower($tipo)."-".strtolower($posicion)." -->";
      $tagEnd = "<!-- end-marco-".strtolower($tipo)."-".strtolower($posicion)." -->";

      //extrae el html respectivo
      $html = self::extraeTextoEntreDosPalabras($template, $tagBegin, $tagEnd);
      
      //reemplaza marcas
      $html = str_replace("{ID_HOLDER_IMAGEN_EXPANDIR_CONTRAER}", (self::isNullOrEmpty($nombreControlImagenExpandirContraer)) ? "" : "id=\"".$nombreControlImagenExpandirContraer."\"", $html);
      $html = str_replace("{CLASS_TITULO}", $classTitulo, $html);
      $html = str_replace("{TITULO}", $titulo, $html);
    } catch (Exception $e) {
      $html = "";
    }
    return $html;
  }




  
//</editor-fold>

}

?>
